﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace SharpFileZillaStats {
    public static class TextTools {

        /// <summary>
        /// Function that return true if the String "text" can be parsed as a number of type "numbertype".
        /// </summary>
        /// <param name="numbertype">the datatype that should be used to parse the number</param>
        /// <param name="text">the string containing a textual representation of a number</param>
        /// <returns>return value: 
        /// == true if "text" is empty string (NULL or "")
        /// == true if "text" can be parsed as type "numbertype"
        /// == false if "text" is not empty and can not be parsed as type "numbertype"
        /// </returns>
        public static bool TryParsingNumber(Type numbertype, String text) { 
            bool has_text = text != null && text.Length > 0;
            Int16 i16;
            Int32 i32;
            Int64 i64;
            UInt16 ui16;
            UInt32 ui32;
            UInt64 ui64;
            Single f16;
            Double f64;
            Decimal dec;

            if(numbertype == typeof(Int16)) return has_text && Int16.TryParse(text, out i16);
            if (numbertype == typeof(Int32)) return has_text && Int32.TryParse(text, out i32);
            if (numbertype == typeof(Int64)) return has_text && Int64.TryParse(text, out i64);
            if (numbertype == typeof(Single)) return has_text && Single.TryParse(text, out f16);
            if (numbertype == typeof(Double)) return has_text && Double.TryParse(text, out f64);
            if (numbertype == typeof(UInt16)) return has_text && UInt16.TryParse(text, out ui16);
            if (numbertype == typeof(UInt32)) return has_text && UInt32.TryParse(text, out ui32);
            if (numbertype == typeof(UInt64)) return has_text && UInt64.TryParse(text, out ui64);
            if (numbertype == typeof(Decimal)) return has_text && Decimal.TryParse(text, out dec);
            throw new Exception("Class: TextTools, Function: TryParsingNumber, Error: Type is not supported");
            
        }



        /// <summary>
        /// Combines a list of String with a given seperator, 
        /// e.g. the String[] {"foo","bar","23"} with the seperator " BLUB "
        /// to "foo BLUB bar BLUB 23"
        /// </summary>
        /// <param name="stringArray"></param>
        /// <param name="seperator"></param>
        /// <returns></returns>
        public static String combine(String[] stringArray, String seperator) {
            StringBuilder SB = new StringBuilder();
            for(int i = 0; i < stringArray.Length; i++) {
                String s = stringArray[i].Trim();
                if(s.Length > 0) {
                    if(i < stringArray.Length - 1) {
                        SB.AppendFormat("{0}{1}", s, seperator);
                    } else {
                        SB.AppendFormat("{0}", s);
                    }
                }
            }
            return SB.ToString();
        }


        public static String combine(System.Collections.IList list, String seperator) {
            StringBuilder SB = new StringBuilder();
            for(int i = 0; i < list.Count; i++) {
                if(i < list.Count - 1) {
                    SB.AppendFormat("{0}{1}", list[i], seperator);
                } else {
                    SB.AppendFormat("{0}", list[i]);
                }
            }
            return SB.ToString();
        }

        public static String combine(DataRow row, String seperator) {
            return TextTools.combine(row.ItemArray, seperator);
        }

        private static String combineTrimmedStrings(List<String> list, string seperator) {
            StringBuilder SB = new StringBuilder();
            for(int i = 0; i < list.Count; i++) {
                if(i < list.Count - 1) {
                    SB.AppendFormat("{0}{1}", list[i], seperator);
                } else {
                    SB.AppendFormat("{0}", list[i]);
                }
            }
            return SB.ToString();
        }

        public static String combine(Object[] objects, string seperator) {
            List<String> valide = new List<string>();
            for(int i = 0; i < objects.Length; i++) {
                if(objects[i] != null && objects[i] != DBNull.Value) {
                    String s = objects[i].ToString().Trim();
                    if(s.Length > 0) valide.Add(s);
                }
            }
            return TextTools.combineTrimmedStrings(valide, seperator);
        }

        /// <summary>
        /// Combines a list of String with a given seperator, 
        /// e.g. the list {"foo","bar","23"} with the seperator " BLUB "
        /// to "foo BLUB bar BLUB 23"
        /// </summary>
        /// <param name="list"></param>
        /// <param name="seperator"></param>
        /// <returns></returns>
        public static String combine(List<String> list, String seperator) {
            List<String> valide = new List<string>();
            foreach(String s in list) {
                if(s != null) {
                    String s2 = s.Trim();
                    if(s2.Length > 0) valide.Add(s2);
                }
            }
            return TextTools.combineTrimmedStrings(valide, seperator);
        }



        public static String combine(List<Int64> list, String seperator) {
            StringBuilder SB = new StringBuilder();
            for(int i=0; i < list.Count; i++) {
                if(i < list.Count - 1) {
                    SB.AppendFormat("{0}{1}", list[i], seperator);
                } else {
                    SB.AppendFormat("{0}", list[i]);
                }
            }

            return SB.ToString();
        }

        public static String combine(List<Object> list, String seperator) {
            return TextTools.combine(list.ToArray(), seperator);
        }

        /// <summary>
        /// Takes an Exception and returns a formatted String showin the Source, Message and the StackTrace Informations.
        /// </summary>
        /// <param name="ex"></param>
        /// <returns></returns>
        public static String Exception2String(Exception ex) {
            return String.Format("Source: {0} \nMessage: {1} \nStackTrace:\n{2}", ex.Source, ex.Message, ex.StackTrace);
        
        }
    }
}
